package com.piece.core.framework.util.async;

import com.alibaba.ttl.threadpool.TtlExecutors;
import com.piece.core.framework.util.basic.SpringUtil;
import com.piece.core.framework.properties.AsyncProperties;
import java.util.TimerTask;
import java.util.concurrent.*;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 定时任务管理器
 */
public class AsyncManager {

    /**
     * 操作延迟
     */
    private int delayTime;

    public void setDelayTime(int delayTime) {
        this.delayTime = delayTime;
    }

    /**
     * 异步操作任务调度线程池
     */
    private ScheduledExecutorService executor;

    public void setExecutor(ScheduledExecutorService executor) {
        this.executor = executor;
    }

    /**
     * 单例模式
     */
    private static AsyncManager instance;
    private static ReentrantLock lock = new ReentrantLock();

    public static AsyncManager getInstance() {
        if (null == instance || null == instance.executor) {
            lock.lock();
            if (null == instance) {
                instance = new AsyncManager();
                AsyncProperties properties = SpringUtil.getBean(AsyncProperties.class);
                instance.setDelayTime(properties.getDelayTime());
                instance.setExecutor(TtlExecutors.getTtlScheduledExecutorService(new ScheduledThreadPoolExecutor(properties.getCorePoolSize())));
            } else if (null == instance.executor) {
                AsyncProperties properties = SpringUtil.getBean(AsyncProperties.class);
                instance.setDelayTime(properties.getDelayTime());
                instance.setExecutor(TtlExecutors.getTtlScheduledExecutorService(new ScheduledThreadPoolExecutor(properties.getCorePoolSize())));
            }
            lock.unlock();
        }
        return instance;
    }

    public Future submit(Runnable runnable) {
        return this.executor.submit(runnable);
    }

    /**
     * 延时执行任务
     */
    public ScheduledFuture execute(TimerTask task) {
        return this.executor.schedule(task, this.delayTime, TimeUnit.MILLISECONDS);
    }

    /**
     * 延时执行任务
     */
    public ScheduledFuture execute(TimerTask task, long time, TimeUnit timeUnit) {
        return this.executor.schedule(task, time, timeUnit);
    }

    /**
     * 周期执行任务
     */
    public ScheduledFuture execute(TimerTask task, long delay, long period, TimeUnit timeUnit) {
        return this.executor.scheduleAtFixedRate(task, delay, period, timeUnit);
    }

    /**
     * 停止任务线程池
     */
    public void shutdown() {
        if (null != this.executor && !this.executor.isShutdown()) {
            this.executor.shutdown();
            try {
                if (!this.executor.awaitTermination(120, TimeUnit.SECONDS)) {
                    this.executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                this.executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    /**
     * 线程等待（毫秒）
     */
    public void sleep(long milliseconds) {
        try {
            Thread.sleep(milliseconds);
        } catch (InterruptedException e) {
            return;
        }
    }
}
